package config

import (
	"strconv"
	"strings"
)

type cfgItem struct {
	Type  string
	Name  string
	Usage string
	Value any
}

func (cfg *cfgItem) parse(list ...ParsedData) {
	for _, m := range list {
		if m == nil {
			continue
		}
		switch cfg.Type {
		case "string":
			v := cfg.Value.(*string)
			if vv, ok := m.Get(cfg.Name); ok {
				*v = vv
			}

		case "strings":
			v := cfg.Value.(*[]string)
			if vv, ok := m.GetAll(cfg.Name); ok {
				*v = vv
			}

		case "int":
			v := cfg.Value.(*int)
			if vv, ok := m.Get(cfg.Name); ok {
				if n, err := strconv.Atoi(vv); err == nil {
					*v = n
				}
			}

		case "ints":
			v := cfg.Value.(*[]int)
			if vv, ok := m.GetAll(cfg.Name); ok {
				vvv := []int{}
				for _, s := range vv {
					if n, err := strconv.Atoi(s); err == nil {
						vvv = append(vvv, n)
					}
				}
				*v = vvv
			}

		case "int64":
			v := cfg.Value.(*int64)
			if vv, ok := m.Get(cfg.Name); ok {
				if n, err := strconv.ParseInt(vv, 10, 64); err == nil {
					*v = n
				}
			}

		case "int64s":
			v := cfg.Value.(*[]int64)
			if vv, ok := m.GetAll(cfg.Name); ok {
				vvv := []int64{}
				for _, s := range vv {
					if n, err := strconv.ParseInt(s, 10, 64); err == nil {
						vvv = append(vvv, n)
					}
				}
				*v = vvv
			}

		case "float64":
			v := cfg.Value.(*float64)
			if vv, ok := m.Get(cfg.Name); ok {
				if n, err := strconv.ParseFloat(vv, 64); err == nil {
					*v = n
				}
			}

		case "float64s":
			v := cfg.Value.(*[]float64)
			if vv, ok := m.GetAll(cfg.Name); ok {
				vvv := []float64{}
				for _, s := range vv {
					if n, err := strconv.ParseFloat(s, 64); err == nil {
						vvv = append(vvv, n)
					}
				}
				*v = vvv
			}

		case "bool":
			v := cfg.Value.(*bool)
			if vv, ok := m.Get(cfg.Name); ok {
				if vv == "" {
					*v = true
				} else if n, err := strconv.ParseBool(vv); err == nil {
					*v = n
				}
			}

		case "bools":
			v := cfg.Value.(*[]bool)
			if vv, ok := m.GetAll(cfg.Name); ok {
				vvv := []bool{}
				for _, s := range vv {
					if s == "" {
						vvv = append(vvv, true)
					} else if n, err := strconv.ParseBool(s); err == nil {
						vvv = append(vvv, n)
					}
				}
				*v = vvv
			}
		}
	}
}

func (it *cfgItem) vstr() string {
	strs := []string{}
	switch it.Type {
	case "string":
		v := it.Value.(*string)
		return *v
	case "strings":
		v := it.Value.(*[]string)
		for _, s := range *v {
			strs = append(strs, s)
		}

	case "int":
		v := it.Value.(*int)
		return strconv.Itoa(*v)
	case "ints":
		v := it.Value.(*[]int)
		for _, n := range *v {
			strs = append(strs, strconv.Itoa(n))
		}

	case "int64":
		v := it.Value.(*int64)
		return strconv.FormatInt(*v, 10)
	case "int64s":
		v := it.Value.(*[]int64)
		for _, n := range *v {
			strs = append(strs, strconv.FormatInt(n, 10))
		}

	case "float64":
		v := it.Value.(*float64)
		return strconv.FormatFloat(*v, 'f', -1, 64)
	case "float64s":
		v := it.Value.(*[]float64)
		for _, n := range *v {
			strs = append(strs, strconv.FormatFloat(n, 'f', -1, 64))
		}

	case "bool":
		v := it.Value.(*bool)
		return strconv.FormatBool(*v)
	case "bools":
		v := it.Value.(*[]bool)
		for _, n := range *v {
			strs = append(strs, strconv.FormatBool(n))
		}

	default:
		return ""
	}
	return strings.Join(strs, ", ")
}
